/* eslint-disable no-param-reassign */
/*
 * @Author: 江舟
 * @LastEditors: 江舟 jijiangzhou@recycloud.cn
 * @LastEditTime: 2024-08-09 11:29:34
 * @Description: file content
 */
import pDefer from 'p-defer';
import EnDecryptAdapter from './enDecryptAdapter';

class AxiosAdapter {
    private axios;
    private axiosConfig;
    private options;
    private EnDecryptAdapter;
    constructor(axios, axiosConfig = {}) {
        this.axios = axios;
        this.axiosConfig = axiosConfig;
        this.options = [];
        this.EnDecryptAdapter = null;
    }
    init(options = []) {
        this.options = options;
        let currentPromise;
        this.options.map((item) => {
            if (item.name === 'EnDecryptAdapter') {
                this.EnDecryptAdapter = new EnDecryptAdapter();
                currentPromise = () => this.EnDecryptAdapter.init(item.options);
            } else if (item.init) {
                item.init(item.options);
            }
        });
        const deferred = pDefer();
        if (this.EnDecryptAdapter && typeof this.EnDecryptAdapter.isEncrypt !== 'boolean') {
            currentPromise().then((res) => {
                this.EnDecryptAdapter.isEncrypt = res;
                deferred.resolve();
            });
        } else {
            deferred.resolve();
        }
        const instance = this.axios.create({
            ...this.axiosConfig,
            ...(this.options.length
                ? {
                      adapter: async (config) => {
                          await deferred.promise;
                          Reflect.deleteProperty(config, 'adapter');
                          this.options.map((item) => {
                              if (item.name === 'EnDecryptAdapter' && this.EnDecryptAdapter) {
                                  config = this.EnDecryptAdapter.requestAdapter(config, item.options || {});
                              } else if (item.requestAdapter) {
                                  config = item.requestAdapter(config, item.options || {});
                              }
                          });
                          return new Promise((resolve, reject) => {
                              this.axios(config)
                                  .then((res) => {
                                      resolve(
                                          this.options.map((item) => {
                                              if (item.name === 'EnDecryptAdapter' && this.EnDecryptAdapter) {
                                                  resolve(this.EnDecryptAdapter.respondseAdapter(res));
                                              } else if (item.respondseAdapter) {
                                                  resolve(item.respondseAdapter(res));
                                              }
                                          }),
                                      );
                                  })
                                  .catch((error) => {
                                      console.error(error);
                                      reject(error);
                                  });
                          });
                      },
                  }
                : {}),
        });
        return instance;
    }
}

export default AxiosAdapter;
